package com.spring.theory.aop.jdkProxy;

import java.lang.reflect.Method;

import lombok.extern.slf4j.Slf4j;

/**
 * TestJdkProxy
 * - jdk代理实现原理
 * <p>
 * 底层采用ASM字节码技术实现
 *
 * @author H
 * @version 1.0
 * @date 2024-01-02 15:59
 */
@Slf4j
public class TestJdkProxy {

    interface TestInterface {
        void test();

        int test2();
    }

    static class ProxyTarget implements TestInterface {
        @Override
        public void test() {
            log.info("ProxyTarget test..");
        }

        @Override
        public int test2() {
            log.info("target test2..");
            return 1;
        }
    }

    /**
     * 对于不确定但却需要执行的方法，使用接口抽象出来；具体实现交给外部定义
     */
    interface InvokeHandler {
        /**
         * 接收方法和方法参数;以便于精确查找应该执行的方法；返回值设计成Object类型，以便于返回任意类型
         */
        Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
    }

    public static void main(String[] args) {
        /**
         * 待增强对象
         */
        ProxyTarget proxyTarget = new ProxyTarget();
        $ProxyTest $proxyTest = new $ProxyTest(new InvokeHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //1.增强
                log.info("====> beafore invoke..");
                //2.执行原有逻辑
                Object result = method.invoke(proxyTarget, args);
                log.info("====> after invoke..");
                return result;
            }
        });
        $proxyTest.test();
        int i = $proxyTest.test2();
        log.info("test2 result=={}", i);

    }

}
